﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Security.Cryptography;

namespace FeaturesBlog.Helpers
{
    public static class SecurityHelper
    {
        public static int CreateRandomSalt()
        {
            Byte[] saltBytes = new Byte[4];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(saltBytes);

            return ((((int)saltBytes[0]) << 24) + (((int)saltBytes[1]) << 16) +
                (((int)saltBytes[2]) << 8) + ((int)saltBytes[3]));
        }

        public static string ComputeHashedPassword(string password, int salt)
        {
            // Create Byte array of password string
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[] secretBytes = encoder.GetBytes(password);

            // Create a new salt
            Byte[] saltBytes = new Byte[4];
            saltBytes[0] = (byte)(salt >> 24);
            saltBytes[1] = (byte)(salt >> 16);
            saltBytes[2] = (byte)(salt >> 8);
            saltBytes[3] = (byte)(salt);

            // append the two arrays
            Byte[] toHash = new Byte[secretBytes.Length + saltBytes.Length];
            Array.Copy(secretBytes, 0, toHash, 0, secretBytes.Length);
            Array.Copy(saltBytes, 0, toHash, secretBytes.Length, saltBytes.Length);

            SHA1 sha1 = SHA1.Create();
            Byte[] computedHash = sha1.ComputeHash(toHash);

            string ask2 = string.Empty;
            foreach (byte b in computedHash) ask2 += "" + (byte)b;
            return ask2.GetHashCode().ToString();//encoder.GetString(computedHash);
        }

        public static string IntEncode(int number)
        {
            int salt = CreateRandomSalt();
            string hash = ComputeHashedPassword(number.ToString(), salt);

            int encNumber = number + salt;
            Encoding e = Encoding.UTF8;

            Byte[] hashBytes = e.GetBytes(hash);
            //int2byte[]
            Byte[] saltBytes = new Byte[4];
            Byte[] numBytes = new Byte[4];
            Byte[] encArray = new Byte[hashBytes.Length + saltBytes.Length + numBytes.Length];
            saltBytes[0] = (byte)(salt >> 24);
            saltBytes[1] = (byte)(salt >> 16);
            saltBytes[2] = (byte)(salt >> 8);
            saltBytes[3] = (byte)(salt);
            //int2byte[]
            numBytes[0] = (byte)(encNumber >> 24);
            numBytes[1] = (byte)(encNumber >> 16);
            numBytes[2] = (byte)(encNumber >> 8);
            numBytes[3] = (byte)(encNumber);

            Array.Copy(saltBytes, 0, encArray, 0, saltBytes.Length);
            Array.Copy(numBytes, 0, encArray, saltBytes.Length, numBytes.Length);
            Array.Copy(hashBytes, 0, encArray, saltBytes.Length + numBytes.Length, hashBytes.Length);
            return (Convert.ToBase64String(encArray)).Replace("+", "=2B=");
        }

        public static int IntDecode(string encString)
        {
            Encoding e = Encoding.UTF8;
            Byte[] array = Convert.FromBase64String(encString.Replace("=2B=", "+"));
            int salt = ((((int)array[0]) << 24) + (((int)array[1]) << 16) +
                (((int)array[2]) << 8) + ((int)array[3]));
            int number = ((((int)array[4]) << 24) + (((int)array[5]) << 16) +
                (((int)array[6]) << 8) + ((int)array[7]));
            string hash = string.Empty;
            hash = e.GetString(array, 8, array.Length - 8);
            if (!string.Equals(hash, ComputeHashedPassword((number - salt).ToString(), salt)))
                throw new Exception();
            return number - salt;
        }
    }
}